#pragma once
#ifndef __LIT__EXCEPTIONS__HH__
#define __LIT__EXCEPTIONS__HH__

#include <exception>
#include <LitString.h>
#include <LitExceptionTypes.h>

#pragma warning( disable: 4251 )

namespace Lit
{
	struct LIT_API Exception : public std::exception
	{
#ifdef LIT_UNICODE
		typedef String 
#else
		typedef std::wstring str_type;
#endif
		Exception( ExceptionType type, const String &_msg, const String &func_, int _line, const String &_file ) ;
		Exception( const Exception& rk );
		virtual ~Exception( );

		String location() const;
		String error() const;
		
		void _buildFull();

		const String &full() const;

		virtual const char * what() const;

		ExceptionType type() const;
		int line() const;
		const String& file() const;
		const String& message() const;
		const String& function() const;

	protected:
		ExceptionType	mType;
		int				mLine;
		String		mFile;
		String		mMessage;
		String		mFunc;

		String		mFull;
	};
	struct LIT_API RuntimeError : public Exception
	{
		RuntimeError( ExceptionType type, const String &_msg, const String &func_, int _line, const String &_file ) ;
		RuntimeError( const String &_msg, const String &func_, int _line, const String &_file ) ;
		RuntimeError( const RuntimeError & rk  ) ;
		virtual ~RuntimeError( );

		const char* what() const{ return Exception::what(); }

	};
	struct LIT_API LogicError : public Exception
	{
	public:
		LogicError( ExceptionType type, const String &_msg, const String &func_, int _line, const String &_file ) ;
		LogicError( const String &_msg, const String &func_, int _line, const String &_file ) ;
		LogicError( const LogicError & rk );
		virtual ~LogicError( );

		const char* what() const{ return Exception::what(); }

	};

	struct LIT_API NullPointer				: public RuntimeError{NullPointer( const String &msg, const String &func_, int _line, const String &_file ) ;};
	struct LIT_API CastError				: public LogicError	{CastError( const String &varname, const String &from, const String &to, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API ImplementationMissing	: public LogicError	{ImplementationMissing( const String &func_name, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API IOError					: public RuntimeError{IOError( const String &filename, const String& desc, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API InitialisationError		: public LogicError	{InitialisationError( const String &msg, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API ShutdownError			: public LogicError	{ShutdownError( const String &msg, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API InvalidPath				: public RuntimeError{InvalidPath( const String &path, bool directory, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API InvalidParameter			: public LogicError	{InvalidParameter( const String &param, const String &reason, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API MissingParameter			: public LogicError	{MissingParameter( const String &param, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API ItemMissing				: public LogicError	{String item;ItemMissing( const String &item, const String &item_mgr_name, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API ItemDuplicate			: public LogicError	{String item;ItemDuplicate( const String &item, const String &item_mgr_name, const String &func_, int _line, const String &_file ) ;	};
	struct LIT_API FileMissing				: public RuntimeError{String filename;FileMissing( const String &filename, const String &func, int line, const String &file );	};
	struct LIT_API FileDuplicate			: public RuntimeError{String filename;FileDuplicate( const String &filename, const String &func, int line, const String &file );	};
	struct LIT_API ModuleException			: public RuntimeError{String moduleName;ModuleException( const String &module, const String& error, const String &_func , int _line, const String &_file );	};
	struct LIT_API ConsoleError				: public RuntimeError{ConsoleError( const String &desc, const String &func = "", size_t line = 0, const String& file="" );	};
	struct LIT_API ConsoleTerminateError	: public RuntimeError{ConsoleTerminateError( const String &msg, const String &func="", size_t line=0, const String& file="" );	};
	struct LIT_API StreamError				: public RuntimeError{StreamError( const String &desc, const String &name = "<Unknown Stream>", const String &func = "", size_t line = 0, const String &file = "" ); };
};

#define EXC_LOC __FUNCTION__, __LINE__, __FILE__

#pragma warning( default: 4251 )

#endif